/* e100.h - information for Intel 8259ER NIC */

#define INTEL_VENDOR_ID		0x8086
#define INTEL_8259ER_DEVICE_ID	0x1229

/* PCI Configuration Registers */

#define E100_PCI_COMMAND 	0x04
#define E100_PCI_STATUS 	0x06
#define E100_PCI_MEMBASE 	0x10
#define E100_PCI_FLASHBASE 	0x18
#define E100_PCI_IOBASE 	0x14
#define E100_PCI_IRQ 		0x3C

#define E100_IO_IOADDR	0x00
#define E100_IO_IODATA	0x04

#define E100_PCI_CMD_MASK	0x107

#define E100_RX_RING_SIZE 	32
#define E100_TX_RING_SIZE 	32
#define E100_RDSIZE 		sizeof(struct 	e100_rx_desc)
#define E100_TDSIZE 		sizeof(struct 	e100_tx_desc)

/* CSR (Control/Status Registers) */
#define	E100_STATUS	0x0000	/* SCB Status Byte	*/
#define E100_STAT_ACK	0x0001	/* STAT/ACK byte	*/
#define E100_CMD_LO	0x0002	/* The lower command byte	*/
#define E100_CMD_HI	0x0003	/* The higher command byte	*/
#define E100_GEN_PTR	0x0004	/* SCB General Pointer		*/
#define E100_PORT	0x0008	/* Port						*/
#define E100_EEPROM_LO	0x000E	/* EEPROM Control Register	*/
#define E100_EEPROM_HI	0x000F /* EEPROM higher byte		*/
#define E100_MDI_CTRL	0x0010	/* MDI Control Register		*/
#define E100_RX_DMA_CNT	0x0014	/* RX DMA Byte Count		*/

enum cb_status {
	cb_complete	= 0x8000,
	cb_ok	    = 0x2000,
};

enum scb_cmd_hi {
	irq_mask_none = 0x00,
	irq_mask_all  = 0x01,
	irq_sw_gen    = 0x02,
};

/* EEPROM Control Register	*/
enum eeprom_ctrl_lo {
	eesk = 0x01,
	eecs = 0x02,
	eedi = 0x04,
	eedo = 0x08,
};
enum eeprom_op {
	op_write = 0x05,
	op_read  = 0x06,
};

static inline void e100_write_flush(uint16 iobase)
{
	/* Flush previous PCI writes through intermediate bridges
	 * by doing a benign read */
	(void)inb(iobase + E100_STATUS);
}

/* Receive Frame Descriptor */

struct e100_rx_desc {
	uint16 status;	//descriptor's status
	uint16 command;	//descriptor's command word
	uint32 link;	//address of the next descriptor
	uint32 reserved;
	//struct e100_rx_desc *next;	//pointor to the next descriptor
	uint16 actual_count;	//the number of bytes written into the data area
	uint16 size;	//size of data buffer exclude header
	//uint EOF;	
	//unit F;	
	byte data[ETH_BUF_SIZE];
};

enum cb_command {
	cb_nop    = 0x0000,
	cb_iaaddr = 0x0001,
	cb_config = 0x0002,
	cb_multi  = 0x0003,
	cb_tx     = 0x0004,
	cb_ucode  = 0x0005,
	cb_dump   = 0x0006,
	cb_tx_sf  = 0x0008,
	cb_cid    = 0x1f00,
	cb_i      = 0x2000,
	cb_s      = 0x4000,
	cb_el     = 0x8000,
};

enum scb_stat_ack {
	stat_ack_not_ours    = 0x00,
	stat_ack_sw_gen      = 0x04,
	stat_ack_rnr         = 0x10,
	stat_ack_cu_idle     = 0x20,
	stat_ack_frame_rx    = 0x40,
	stat_ack_cu_cmd_done = 0x80,
	stat_ack_not_present = 0xFF,
	stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),
	stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),
};
